package com.alks.function.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.config.handler.AutoCellWriteWidthHandle;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.UserInfoUtil;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.beanutils.StringUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.common.utils.stringUtils.ZStringUtils;
import com.alks.entity.data.entity.PcCuttingProcess;
import com.alks.entity.data.entity.PcCuttingProcessDetail;
import com.alks.entity.data.entity.SdPosition;
import com.alks.entity.data.entity.SdVendor;
import com.alks.entity.data.page.PageRecord;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.sys.SdVendorDto;
import com.alks.function.data.request.sys.PcCuttingProcessDetailRequest;
import com.alks.function.data.request.sys.SdPositionRequest;
import com.alks.function.data.request.sys.SdVendorAddRequest;
import com.alks.function.mapper.SdPositionMapper;
import com.alks.function.mapper.SdUserMapper;
import com.alks.function.service.SdPositionService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class SdPositionServiceImpl extends ServiceImpl<SdPositionMapper, SdPosition> implements SdPositionService {

    @Autowired
    private SdPositionMapper sdPositionMapper;

    @Resource
    private SdUserMapper sdUserMapper;

    /**
     * 分页查询
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo GetSdPosition(SdPositionRequest request) {
        PageRecord<SdPosition> list = new PageRecord<>();
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        List<SdPosition> sdPosition = sdPositionMapper.getSdPosition(request.getPosName(), companyId);
        PageInfo page=new PageInfo(sdPosition);
        list.setList(sdPosition);
        list.setTotal(page.getTotal());
        return ResponseInfo.ok(list);
    }

    /**
     * 添加职务
     * @param sdPosition
     * @return
     */
    @Override
    public ResponseInfo AddSdPosition(SdPosition sdPosition) {
        if (ObjectUtils.isEmpty(sdPosition.getPosId())){
            return ResponseInfo.error("请输入职务代码!");
        }
        if (ObjectUtils.isEmpty(sdPosition.getPosName())){
            return ResponseInfo.error("请输入职务名称!");
        }
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        sdPosition.setCompanyId(companyId);
        SdPosition entity = sdPositionMapper.findPosIdResponseInfo(sdPosition);
        if (!ObjectUtils.isEmpty(entity)){
            return ResponseInfo.error("该职务代码已存在,不可重复添加!");
        }
        save(sdPosition);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除
     * @param posId
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo delPosition(String posId) {
        if (ObjectUtils.isEmpty(posId)){
            return ResponseInfo.error("职务代码不能为空!");
        }
        Integer count = sdUserMapper.getPosId(posId);
        if (count != null && count > 0) {
            return ResponseInfo.error("该职务已使用,不可删除!");
        }
        sdPositionMapper.delPosition(posId);
        sdPositionMapper.delSdPrgPrivilege(posId);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 修改
     * @param sdPosition
     * @return
     */
    @Override
    public ResponseInfo updateSdPosition(SdPosition sdPosition) {
        if (ObjectUtils.isEmpty(sdPosition.getPosId())){
            return ResponseInfo.error("职务代码不能为空!");
        }
        if (ObjectUtils.isEmpty(sdPosition.getPosName())){
            return ResponseInfo.error("职务名称不能为空!");
        }
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        sdPosition.setCompanyId(companyId);
        LambdaUpdateWrapper<SdPosition> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SdPosition::getPosId,sdPosition.getPosId()).eq(SdPosition::getCompanyId,companyId);
        sdPositionMapper.update(sdPosition,wrapper);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 工序资料查询
     * @return
     */
    @Override
    public ResponseInfo ProcessDataQuery() {
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        List<Map<String, String>> process = sdPositionMapper.getProcess(companyId);
        return ResponseInfo.ok(process);
    }

    /**
     * 工序资料
     * @param processCode
     * @param processName
     * @param choose
     * @return
     */
    @Override
    public ResponseInfo pcCuttingProcess(String processCode, String processName, Integer choose) {
        if (ObjectUtils.isEmpty(processCode)){
            return ResponseInfo.ok("工序代码不能为空!");
        }
        if (ObjectUtils.isEmpty(processName)){
            return ResponseInfo.error("工序名称不能为空!");
        }
        if (processCode.length()>2){
            return ResponseInfo.error("工序代码长度不能超过2位!");
        }
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        switch (choose) {
            case 0:
                AddPcCuttingProcess(processCode, processName,companyId);
                break;
            case 1:
                UpdatePcCuttingProcess(processCode,processName,companyId);
                break;
            case 2:
                DeletePcCuttingProcess(processCode, companyId);
                break;
            default:
                return ResponseInfo.error("请选择操作!");
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 添加工序
     * @param processCode
     * @param processName
     * @param companyId
     */
    private void AddPcCuttingProcess(String processCode, String processName,String companyId) {
        String process = sdPositionMapper.getPcCuttingProcess(companyId, processCode);
        if (!ObjectUtils.isEmpty(process)){
           throw new ServiceErrorException(processCode +"工序代码已存在,不可重复添加!");
        }
        PcCuttingProcess pcCuttingProcess = new PcCuttingProcess();
        pcCuttingProcess.setCompanyId(companyId);
        pcCuttingProcess.setProcessCode(processCode);
        pcCuttingProcess.setProcessName(processName);
        sdPositionMapper.AddPcCuttingProcess(pcCuttingProcess);
    }

    /**
     * 工序修改
     * @param processCode
     * @param processName
     * @param companyId
     */
    private void UpdatePcCuttingProcess(String processCode, String processName,String companyId) {
        sdPositionMapper.UpdatePcCuttingProcess(processCode,processName,companyId);
    }

    /**
     * 删除工序
     * @param processCode
     * @param companyId
     */
    private void DeletePcCuttingProcess(String processCode, String companyId) {
        int count = sdPositionMapper.getPcCuttingProcessDetailToProcessCode(companyId, processCode);
        if (count > 0) {
            throw new ServiceErrorException("该工序下存在工艺资料,无法删除该记录!");
        } else {
            sdPositionMapper.DeletePcCuttingProcess(processCode, companyId);
        }
    }

    /**
     * 工艺查询
     * @param processCode
     * @return
     */
    @Override
    public ResponseInfo PcCuttingProcessDetailQuery(String processCode) {
        String companyId = UserInfoUtil.getUserInfo().getCompanyId();
        List<PcCuttingProcessDetail> list = sdPositionMapper.getPcCuttingProcessDetailList(companyId, processCode);
        return ResponseInfo.ok(list);
    }

    /**
     * 工艺资料
     * @param request
     * @param choose
     * @return
     */
    @Override
    public ResponseInfo PcCuttingProcessDetail(PcCuttingProcessDetailRequest request, Integer choose) {
        if (ObjectUtils.isEmpty(request.getProcessCode())){
            return ResponseInfo.error("工序代码不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getSeqNo())){
            return ResponseInfo.error("序号不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getProcess())){
            return ResponseInfo.error("工艺不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getCompanyId())){
            return ResponseInfo.error("公司代码不能为空!");
        }
        switch (choose) {
            case 0:
                AddPcCuttingProcessDetail(request);
                break;
            case 1:
                UpdatePcCuttingProcessDetail(request);
                break;
            case 2:
                DeletePcCuttingProcessDetail(request);
                break;
            default:
                return ResponseInfo.error("请选择操作!");
        }
        return ResponseInfo.ok("操作成功!");
    }

    private void DeletePcCuttingProcessDetail(PcCuttingProcessDetailRequest request) {
        sdPositionMapper.DeletePcCuttingProcessDetail(request);
    }

    private void UpdatePcCuttingProcessDetail(PcCuttingProcessDetailRequest request) {
        sdPositionMapper.UpdatePcCuttingProcessDetail(request);
    }

    private void AddPcCuttingProcessDetail(PcCuttingProcessDetailRequest request) {
        String seqNo = sdPositionMapper.getPcCuttingProcessDetailToSeqNo(request);
        if (!ObjectUtils.isEmpty(seqNo)){
            throw new ServiceErrorException(request.getSeqNo() +"序号已存在,不可重复添加!");
        }
        sdPositionMapper.AddPcCuttingProcessDetail(request);
    }

    /**
     * 添加厂商
     * @param request
     * @return
     */
    @Override
    public ResponseInfo SdVendorAdd(SdVendorAddRequest request) {
        if (ObjectUtils.isEmpty(request.getVendorType())){
            return ResponseInfo.error("请选择厂商类别!");
        }
        if (ObjectUtils.isEmpty(request.getVendorNo())){
            return ResponseInfo.error("厂商代码不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getVendorAbbr())){
            return ResponseInfo.error("厂商简称不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getVendorName())){
            return ResponseInfo.error("厂商名称不能为空!");
        }
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        String vendorNo = sdPositionMapper.getVendorNo(request.getVendorNo(), userInfo.getCompanyId());
        if (ZStringUtils.isNotEmpty(vendorNo)){
            return ResponseInfo.error("厂商代码已存在,不可重复添加!");
        }
        String vendorAbbr = sdPositionMapper.getVendorAbbr(request.getVendorAbbr(), userInfo.getCompanyId());
        if (ZStringUtils.isNotEmpty(vendorAbbr)){
            return ResponseInfo.error("厂商简称已存在,不可重复添加!");
        }
        SdVendor sdVendor = new SdVendor();
        BeanUtil.copyProperties(request, sdVendor);
        sdVendor.setCompanyId(userInfo.getCompanyId());
        sdVendor.setDelFlag(BigDecimal.ZERO);
        sdVendor.setSysUser(userInfo.getUserName());
        sdVendor.setSysDate(new Date());
        sdPositionMapper.addSdVendor(sdVendor);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 厂商列表
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo SdVendorList(SdVendorAddRequest request) {
        PageRecord<SdVendorDto> list = new PageRecord<>();
        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        List<SdVendorDto> sdVendorList = sdPositionMapper.getSdVendorList(request);
        list.setList(sdVendorList);
        PageInfo pageInfo = new PageInfo(sdVendorList);
        list.setTotal(pageInfo.getTotal());
        return ResponseInfo.ok(list);
    }

    /**
     * 修改厂商
     * @param request
     * @return
     */
    @Override
    public ResponseInfo SdVendorUpdate(SdVendorAddRequest request) {
        if (ObjectUtils.isEmpty(request.getVendorNo())){
            return ResponseInfo.error("厂商代码不能为空!");
        }
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        SdVendor sdVendor = new SdVendor();
        BeanUtil.copyProperties(request, sdVendor);
        sdVendor.setCompanyId(userInfo.getCompanyId());
        sdVendor.setSysUser(userInfo.getUserName());
        sdVendor.setSysDate(new Date());
        sdPositionMapper.updateSdVendor(sdVendor);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除厂商
     * @param request
     * @return
     */
    @Override
    public ResponseInfo SdVendorDel(SdVendorAddRequest request) {
        if (ObjectUtils.isEmpty(request.getVendorNo())){
            return ResponseInfo.error("厂商代码不能为空!");
        }
        if ("Y".equals(request.getFlag())){
            return ResponseInfo.error("该厂商已使用,不可删除!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        sdPositionMapper.delSdVendor(request.getVendorNo(),companyId);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 导出厂商明细
     * @param request
     * @param response
     */
    @Override
    @AutoPageAop
    public void exportSdVendor(SdVendorAddRequest request, HttpServletResponse response) {
        String companyId = UserIdThread.get().getCompanyId();
        request.setCompanyId(companyId);
        List<SdVendorDto> sdVendorList = sdPositionMapper.getSdVendorList(request);
        if (ObjectUtils.isEmpty(sdVendorList)){
            throw new ServiceErrorException("查询厂商明细为空!");
        }
        String fileName = "厂商明细" + DateUtils.dateTimeNow() + ".xls";
        try (
                InputStream inputStream = new ClassPathResource("templates/厂商明细模板.xls").getInputStream();
                OutputStream outputStream = response.getOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream).excelType(ExcelTypeEnum.XLS).withTemplate(inputStream).registerWriteHandler(new AutoCellWriteWidthHandle()).build();
        ) {
            ExcelUtils.setResponseZF(response, fileName);
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(new FillWrapper("t", sdVendorList), fillConfig, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            log.error("厂商明细导出失败, 错误信息: {}", e.getMessage(), e);
            throw new ServiceErrorException("厂商明细导出失败!");
        }
    }

    @Override
    public String getNameByNo(String vendorNo) {
        String companyId = UserIdThread.get().getCompanyId();
        String vendorName = sdPositionMapper.getNameByNo(vendorNo,companyId);
        if (StringUtils.isBlank(vendorName)){
            log.warn("\n异常接口：getNameByNo\n异常原因：找不到厂商ID\n对应表【SD_VENDOR】\n查询参数：vendorNo：{}",vendorNo);
            throw new ServiceErrorException("厂商不存在");
        }
        return vendorName;
    }
}
